/**
 * 批量更新管理器 - Phase 1 性能优化
 * 将多个小的更新操作合并成批处理，减少重新渲染频率
 */

// 更新任务接口
interface UpdateTask {
  id: string;
  fn: () => void;
  priority: number; // 优先级：1-高，2-中，3-低
  timestamp: number;
}

// 批量更新配置
interface BatchUpdateConfig {
  maxBatchSize: number; // 每批最大任务数
  batchDelay: number; // 批处理延迟(ms)
  maxDelay: number; // 最大延迟时间(ms)
}

// 默认配置
const DEFAULT_CONFIG: BatchUpdateConfig = {
  maxBatchSize: 10, // 每批最多10个任务
  batchDelay: 16, // 16ms延迟（约60fps）
  maxDelay: 100 // 最大延迟100ms
};

/**
 * 批量更新管理器类
 */
export class BatchUpdateManager {
  private pendingTasks = new Map<string, UpdateTask>();
  private config: BatchUpdateConfig;
  private batchTimer: number | null = null;
  private lastFlushTime = 0;

  constructor(config: Partial<BatchUpdateConfig> = {}) {
    this.config = { ...DEFAULT_CONFIG, ...config };
  }

  /**
   * 添加更新任务
   * @param id 任务唯一标识符
   * @param fn 更新函数
   * @param priority 优先级（1-高，2-中，3-低）
   */
  scheduleUpdate(id: string, fn: () => void, priority: number = 2): void {
    const now = Date.now();

    // 添加或更新任务
    this.pendingTasks.set(id, {
      id,
      fn,
      priority,
      timestamp: now
    });

    // 检查是否需要立即刷新（高优先级或超时）
    const shouldFlushImmediately =
      priority === 1 ||
      now - this.lastFlushTime > this.config.maxDelay ||
      this.pendingTasks.size >= this.config.maxBatchSize;

    if (shouldFlushImmediately) {
      this.flushUpdates();
    } else {
      this.scheduleBatch();
    }
  }

  /**
   * 取消更新任务
   * @param id 任务标识符
   */
  cancelUpdate(id: string): boolean {
    return this.pendingTasks.delete(id);
  }

  /**
   * 立即执行所有待处理的更新
   */
  flushUpdates(): void {
    if (this.batchTimer) {
      clearTimeout(this.batchTimer);
      this.batchTimer = null;
    }

    if (this.pendingTasks.size === 0) {
      return;
    }

    // 按优先级排序任务
    const tasks = Array.from(this.pendingTasks.values()).sort((a, b) => {
      // 首先按优先级排序
      if (a.priority !== b.priority) {
        return a.priority - b.priority;
      }
      // 相同优先级按时间戳排序
      return a.timestamp - b.timestamp;
    });

    // 执行任务
    const startTime = performance.now();
    let executedCount = 0;

    for (const task of tasks) {
      try {
        task.fn();
        executedCount++;

        // 时间片控制：如果执行时间过长，分批执行
        const elapsed = performance.now() - startTime;
        if (elapsed > 5 && executedCount < tasks.length) {
          // 保留未执行的任务，下次继续
          const remainingTasks = tasks.slice(executedCount);
          this.pendingTasks.clear();
          remainingTasks.forEach((t) => this.pendingTasks.set(t.id, t));

          // 立即安排下一批
          this.scheduleBatch(0);
          break;
        }
      } catch (error) {
        console.error(`Batch update task ${task.id} failed:`, error);
      }
    }

    // 如果全部执行完成，清空任务队列
    if (executedCount === tasks.length) {
      this.pendingTasks.clear();
    }

    this.lastFlushTime = Date.now();
  }

  /**
   * 安排批量更新
   * @param delay 延迟时间，默认使用配置的延迟
   */
  private scheduleBatch(delay?: number): void {
    if (this.batchTimer) {
      return; // 已经有定时器在运行
    }

    const actualDelay = delay ?? this.config.batchDelay;

    this.batchTimer = window.setTimeout(() => {
      this.batchTimer = null;
      this.flushUpdates();
    }, actualDelay);
  }

  /**
   * 获取统计信息
   */
  getStats() {
    const priorityCounts = { high: 0, medium: 0, low: 0 };

    for (const task of this.pendingTasks.values()) {
      switch (task.priority) {
        case 1:
          priorityCounts.high++;
          break;
        case 2:
          priorityCounts.medium++;
          break;
        case 3:
          priorityCounts.low++;
          break;
      }
    }

    return {
      pendingTasks: this.pendingTasks.size,
      priorityCounts,
      isScheduled: this.batchTimer !== null,
      config: this.config
    };
  }

  /**
   * 清理所有任务
   */
  clear(): void {
    this.pendingTasks.clear();
    if (this.batchTimer) {
      clearTimeout(this.batchTimer);
      this.batchTimer = null;
    }
  }

  /**
   * 销毁管理器
   */
  destroy(): void {
    this.clear();
  }
}

// 全局批量更新管理器实例
export const globalBatchUpdateManager = new BatchUpdateManager({
  maxBatchSize: 8, // 适度的批量大小
  batchDelay: 16, // 60fps对应的延迟
  maxDelay: 80 // 较短的最大延迟保证响应性
});

/**
 * 便捷的批量更新调度函数
 */
export function scheduleBatchUpdate(id: string, fn: () => void, priority: number = 2): void {
  globalBatchUpdateManager.scheduleUpdate(id, fn, priority);
}

/**
 * 取消批量更新
 */
export function cancelBatchUpdate(id: string): boolean {
  return globalBatchUpdateManager.cancelUpdate(id);
}

/**
 * 立即刷新所有待处理更新
 */
export function flushBatchUpdates(): void {
  globalBatchUpdateManager.flushUpdates();
}
